package com.garlicts.framework.crawler;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebRequest;
import com.gargoylesoftware.htmlunit.WebResponse;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.garlicts.framework.crawler.common.MapUtil;
import com.garlicts.framework.crawler.common.StringUtil;

public class CrawlerTemplate {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(CrawlerTemplate.class);

	WebClientPool webClientPool;
	
	public CrawlerTemplate(Integer crawlerNumber) {
		
		webClientPool = new WebClientPool(crawlerNumber);
		
	}
	
	/**
	 * 获取一个webclient实例 
	 * @return
	 */
	public WebClient borrowWebClient() {
		
		WebClient webClient = null;
		
		try {
			webClient = webClientPool.borrowObject();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return webClient;
		
	}
	
	/**
	 * 归还webclient实例
	 * @param webClient
	 */
	public void returnWebClient(WebClient webClient) {
		webClientPool.returnObject(webClient);
	}
	
	public int getNumIdle() {
		return webClientPool.getNumIdle();
	}
	
	public RootPage execute(CrawlerHttpRequest crawlerHttpRequest) throws FailingHttpStatusCodeException, IOException{
		
		String url = crawlerHttpRequest.getUrl();
		RootPage rootPage = new RootPage();
		
		WebClient webClient = borrowWebClient();
		WebRequest webRequest = buildWebRequest(crawlerHttpRequest);
		HtmlPage htmlPage = webClient.getPage(webRequest);
		
		WebResponse webResponse = htmlPage.getWebResponse();
		int statusCode = webResponse.getStatusCode();
		if(statusCode != 200){
			StringBuilder logStr = new StringBuilder();
			logStr.append("爬取url[").append(url).append("]失败，http status code is ").append(statusCode);
			LOGGER.error(logStr.toString());
			rootPage.setSuccess(false);
		}else {
			rootPage.setSuccess(true);
			rootPage.setHtmlPage(htmlPage);
			rootPage.setWebClient(webClient);
		}
		
		return rootPage;
		
	}
	
	public WebRequest buildWebRequest(CrawlerHttpRequest crawlerHttpRequest){
		
		String url = crawlerHttpRequest.getUrl();
		Map<String,String> additionalHeaders = crawlerHttpRequest.getRequestHeaderMap();
		if(MapUtil.isEmpty(additionalHeaders)){
			
			additionalHeaders = new HashMap<String,String>();
			additionalHeaders.put("accept-language", "zh-CN,zh;q=0.8");
			
		}
		
		String proxyAddress = crawlerHttpRequest.getProxyAddress();
		
		URL link;
		WebRequest webRequest = null;
		
		try {
			link = new URL(url);
			webRequest = new WebRequest(link);
			
			if(StringUtil.isNotEmpty(proxyAddress)){
				
				String[] proxyAddr = proxyAddress.split(proxyAddress);
				
				webRequest.setProxyHost(proxyAddr[0]);
				webRequest.setProxyPort(Integer.parseInt(proxyAddr[1]));
				
			}

			webRequest.setAdditionalHeaders(additionalHeaders);
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		
		return webRequest;
	}
	
}
